"""
FastMCP Demo Project
Main entry point for the FastAPI + FastMCP application
"""

import asyncio
import uvicorn
from fastapi import FastAPI
from contextlib import asynccontextmanager
from pp_mcp.server import create_mcp_server
from api.routes import api_router, setup_proxy_routes
from api.proxy_routes import get_proxy_router, setup_proxy_manager
from config import settings


# Global variables for server instances
mcp_server = None
proxy_registry = None
mcp_app = None


@asynccontextmanager
async def lifespan(app: FastAPI):
    """Lifespan manager for the FastAPI application"""
    global mcp_server, proxy_registry, mcp_app

    print("FastAPI application starting up...")

    # Create MCP server and proxy registry
    mcp_server, proxy_registry = await create_mcp_server()

    # Setup proxy API routes
    setup_proxy_routes(proxy_registry.get_manager())

    # Setup independent proxy router with its own prefix
    setup_proxy_manager(proxy_registry.get_manager())

    # Configure HTTP app for stateless mode to avoid session management issues
    mcp_app = mcp_server.http_app(path="/", stateless_http=True)

    # Store MCP server and proxy registry in app state
    app.state.mcp_server = mcp_server
    app.state.proxy_registry = proxy_registry

    # Start MCP app lifespan - this is critical for session manager initialization
    async with mcp_app.lifespan(app):
        print("MCP server initialized and ready")

        # Mount the MCP application during startup
        if mcp_app:
            app.mount("/mcp", mcp_app)

        yield

    print("FastAPI application shutting down...")

    # Cleanup proxies
    if proxy_registry:
        await proxy_registry.get_manager().stop_all_proxies()


# Create FastAPI application with the combined lifespan
app = FastAPI(
    title="FastMCP Demo",
    description="A demonstration project combining FastAPI and FastMCP v2 with dynamic proxy management",
    version="1.0.0",
    lifespan=lifespan,
)

# Include API routes
app.include_router(api_router, prefix="/api/v1")

# Include proxy routes with separate prefix
app.include_router(get_proxy_router(), prefix="/api/v1")


@app.get("/")
async def root():
    """Root endpoint"""
    return {
        "message": "Welcome to FastMCP Demo with Dynamic Proxy Management",
        "version": "1.0.0",
        "docs": "/docs",
        "api": "/api/v1",
        "mcp": "/mcp",
        "proxy_api": "/api/v1/proxies",
    }


@app.get("/health")
async def health_check():
    """Health check endpoint"""
    return {"status": "healthy", "service": "fastmcp-demo"}


def run_fastapi():
    """Run the FastAPI application"""
    print("Starting FastAPI server...")
    uvicorn.run(
        "main:app",
        host=settings.HOST,
        port=settings.PORT,
        reload=settings.DEBUG,
        log_level="info",
    )


def run_mcp_standalone():
    """Run FastMCP server standalone (STDIO)"""
    print("Starting FastMCP server in standalone mode...")

    async def main():
        mcp_server, proxy_registry = await create_mcp_server()
        # Run with STDIO transport (default)
        mcp_server.run()

    asyncio.run(main())


async def run_mcp_async():
    """Run FastMCP server asynchronously"""
    print("Starting FastMCP server asynchronously...")

    mcp_server, proxy_registry = await create_mcp_server()
    await mcp_server.run_async(
        transport="http", host=settings.MCP_HOST, port=settings.MCP_PORT
    )


if __name__ == "__main__":
    import sys

    # Check command line arguments
    if len(sys.argv) > 1:
        mode = sys.argv[1].lower()

        if mode == "fastapi":
            # Run FastAPI with integrated MCP
            run_fastapi()
        elif mode == "mcp":
            # Run MCP standalone
            run_mcp_standalone()
        elif mode == "mcp-http":
            # Run MCP as HTTP server
            asyncio.run(run_mcp_async())
        else:
            print(f"Unknown mode: {mode}")
            print("Available modes: fastapi, mcp, mcp-http")
            sys.exit(1)
    else:
        # Default: Run with both FastAPI and MCP integrated
        run_fastapi()
